package top.lishuoboy.hibernate.validator.service.common;

import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * validator校验服务。直接抛异常
 * <p>
 * 2024/10/29
 *
 * @author lishuoboy
 */
@RequiredArgsConstructor
@Component
public class ValidatorService {
    private final Validator validator;

    /** bean校验 */
    public <T> void validate(T object, Class<?>... groups) {
        throwConstraintViolationException(validator.validate(object, groups));
    }

    /** bean校验-对象的1个字段 */
    public <T> void validateProperty(T object, String propertyName, Class<?>... groups) {
        throwConstraintViolationException(validator.validateProperty(object, propertyName, groups));
    }

    /** bean校验-类的1个字段 */
    public <T> void validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
        throwConstraintViolationException(validator.validateValue(beanType, propertyName, value, groups));
    }

    /** 方法参数校验 */
    public <T> void validateParameters(T object, Method method, Object[] parameterValues, Class<?>... groups) {
        throwConstraintViolationException(validator.forExecutables().validateParameters(object, method, parameterValues, groups));
    }

    /** 构造方法参数校验 */
    public <T> void validateConstructorParameters(Constructor<? extends T> constructor, Object[] parameterValues, Class<?>... groups) {
        throwConstraintViolationException(validator.forExecutables().validateConstructorParameters(constructor, parameterValues, groups));
    }

    /** 方法返回值校验 */
    public <T> void validateReturnValue(T object, Method method, Object returnValue, Class<?>... groups) {
        throwConstraintViolationException(validator.forExecutables().validateReturnValue(object, method, returnValue, groups));
    }

    /** 构造方法返回值校验 */
    public <T> void validateConstructorReturnValue(Constructor<? extends T> constructor, Object[] parameterValues, Class<?>... groups) {
        throwConstraintViolationException(validator.forExecutables().validateConstructorReturnValue(constructor, parameterValues, groups));
    }


    private <T> void throwConstraintViolationException(Set<ConstraintViolation<T>> constraintViolationSet) {
        if (CollUtil.isNotEmpty(constraintViolationSet)) {
            throw new ConstraintViolationException(constraintViolationSet);
        }
    }
}
